<template>
  <div>
    <el-form label-width="80px" :model='spu'>
      <el-form-item label="SPU名称">
        <el-input  placeholder="请输入SPU名称" v-model='spu.spuName'></el-input>
      </el-form-item>
      <el-form-item label="品牌" >
        <el-select  placeholder="请选择品牌" v-model='spu.tmId'>
          <el-option :label='tm.tmName' :value='tm.id' v-for='tm in tradeMarkList' :key='tm.id'></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="SPU描述">
          <el-input type='textarea' placeholder="描述" rows='4' v-model='spu.description'></el-input>
      </el-form-item>
      <el-form-item label="SPU图片">
        <!-- 
          action上传图片地址 
          list-type文件列表类型
          :on-preview="handlePictureCardPreview" 预览触发
          :on-remove="handleRemove" 删除触发
          展示： :file-list="spuImageList" 数组必须有name 和 url字段
        -->
        <el-upload
          action='/dev-api//admin/product/fileUpload'
          list-type="picture-card"
          :file-list="spuImageList"
          :on-preview="handlePictureCardPreview"
          :on-remove="handleRemove"
          :on-success='handleSuccess'
          >
          <i class="el-icon-plus"></i>
        </el-upload>
        <el-dialog :visible.sync="dialogVisible">
          <img width="100%" :src="dialogImageUrl" alt="">
        </el-dialog>
      </el-form-item>
      <el-form-item label="销售属性">
        <el-select  :placeholder="`还有${unSelectSaleAttr.length}条未选择`" v-model='attrIdAndAttrName'>
          <el-option :label="unSelect.name" :value="`${unSelect.id}: ${unSelect.name}`" v-for='unSelect in unSelectSaleAttr' :key='unSelect.id'></el-option>
        </el-select>
        <el-button type="primary" icon='el-icon-plus' style='margin: 10px' :disabled='!attrIdAndAttrName' @click='addSaleAttr'>添加销售属性</el-button>
        <el-table border :data='spu.spuSaleAttrList'>
          <el-table-column label="序号" width='80' align='center' type=index></el-table-column>
          <el-table-column label="属性名" width='150' prop='saleAttrName'></el-table-column>
          <el-table-column label="属性值名称列表">
            <!-- @close="handleClose(tag)"
              @keyup.enter.native="handleInputConfirm"
              @click="showInput"
             -->
            <template v-slot='{row}'>
              <!-- 展示已有的属性值 -->
              <el-tag :key="tag.id" v-for="(tag, index) in row.spuSaleAttrValueList" closable :disable-transitions="false" 
              @close="handleClose(row, index)">
                {{tag.saleAttrValueName}}
              </el-tag>
              <!-- 底下的结构类似span 与input的切换 -->
              <el-input class="input-new-tag" 
                v-if="row.inputVisible"
                v-model="row.inputValue"
                ref="saveTagInput"
                size="small"
                @blur="handleInputConfirm (row)">
              </el-input>
              <el-button v-else class="button-new-tag" size="small" @click='addSaleAttrValue (row)'>+ 添 加</el-button>
            </template>
          </el-table-column>
          <el-table-column label="操作" width='120'>
            <template v-slot='{row, $index}'>
              <el-button type="danger" icon='el-icon-delete' size='mini' @click='deleteAttr($index, row)'></el-button>
            </template>
          </el-table-column>
        </el-table>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click='addOrUpdateSpu'>保存</el-button>
        <el-button @click='cancel'>取消</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
export default {
  name: 'SpuForm',
  data () {
    return {
      dialogImageUrl: '',
      dialogVisible: false,
      // 获取spu请求信息,初始化是空对象，请求会返回对象，点击修改的时候v-model可以收集到；但是点击添加的时候，收集到哪 收集哪些字段要写好
      spu: {
        category3Id: 0,
        description: "",
        spuName: "",
        tmId: '',
        spuImageList: [
          // {
          //   id: 0,
          //   imgName: "",
          //   imgUrl: "",
          //   spuId: 0
          // }
        ],
        spuSaleAttrList: [
          // {
          //   baseSaleAttrId: '',
          //   id: '',
          //   saleAttrName: "",
          //   spuId: '',
          //   spuSaleAttrValueList: [
          //     {
          //       baseSaleAttrId: '',
          //       id: '',
          //       isChecked: "",
          //       saleAttrName: "",
          //       saleAttrValueName: "",
          //       spuId: ''
          //     }
          //   ]
          // }
        ]
      }, 
      tradeMarkList: [], // 获取品牌
      spuImageList: [], //获取spu图片
      saleAttrList: [], // 销售属性获取
      // 收集未选择的销售属性id
      attrIdAndAttrName: ''
    };
  },
  methods: {
    handleRemove(file, fileList) {
      // 参数：删除掉的和剩下的图片数组
      // console.log(file, fileList);
      // 收集照片墙list,对于服务器不需要name和url字段
      this.spuImageList = fileList
    },
    handlePictureCardPreview(file) {
      // 将图片地址赋值
      this.dialogImageUrl = file.url;
      // 对话框显示
      this.dialogVisible = true;
    },
    // 图片上传成功回调
    handleSuccess (response, file, fileList) {
      // console.log (response, file, fileList)
      this.spuImageList = fileList
    },
    // 发请求的方法，在父组件更新按钮的事件中调用 多次
    async initSpuData (spu) {
      // 获取spu信息请求
      let spuResult = await this.$API.spu.reqSpu (spu.id)
      // console.log (spuResult)
      if (spuResult.code == 200) {
        this.spu = spuResult.data
      }
      // 获取品牌的请求
      let tradeMarkResult = await this.$API.spu.reqTradeMarkList ()
      if (tradeMarkResult.code == 200) {
        this.tradeMarkList = tradeMarkResult.data
      }
      // 获取spu图片请求
      let spuImageResult = await this.$API.spu.reqSpuImageList (spu.id)
      if (spuImageResult.code == 200) {
        // 动态展示照片墙的时候el-load要求是一个数组，数组里有name和url属性 处理后再存储
        let listAttr = spuImageResult.data
        listAttr.forEach (item => {
          item.name = item.imgName
          item.url = item.imgUrl
        })
        this.spuImageList = listAttr
      }
      // 获取销售属性
      let saleResult = await this.$API.spu.reqBaseSaleAttrList () 
      if (saleResult.code == 200) {
        this.saleAttrList = saleResult.data
      }
    },
    // 添加新的销售属性
    addSaleAttr () {
      // 已经收集到attrIdAndAttrName   2：版本
      // 把收集到的分割  添加到展示出数据来源那
      const [baseSaleAttrId, saleAttrName] = this.attrIdAndAttrName.split (':')
      let newAttr = {baseSaleAttrId,  saleAttrName, spuSaleAttrValueList: []}
      this.spu.spuSaleAttrList.push (newAttr)
      // 清空数据
      this.attrIdAndAttrName = ''
    },
    // 点击添加销售属性值，需要展示为input,通过当前销售属性inputVisible字段控制，但是本身没有这个字段,响应式添加
    addSaleAttrValue (row) {
      this.$set (row, 'inputVisible', true)
      // 属性值收集到哪，响应式添加
      this.$set (row, 'inputValue', '')
      // 自动获取焦点 原因就出在"this.inputVisible = true",此时数据虽然变化了,但是文本框还没有渲染展示到页面上,
      // 所以就拿不到它的引用ref,去调用focus()方法就会报错为 undefined;
      this.$nextTick (() => {
        this.$refs.saveTagInput.focus ()
      })
    },
    // input失去焦点显示button 并且展示新添加的属性值,还要判断是否重复输入 是否为空
    handleInputConfirm (row) {
      // 显示button,收集到的属性值放到已有的展示出来的数组那里，需要整理数据
      const {baseSaleAttrId, inputValue} = row
      // 判断是否重复输入 是否为空
      if (inputValue.trim() == '') {
        this.$message ('属性值不能为空')
        row.inputVisible = false
        return
      }
      let result = row.spuSaleAttrValueList.every (item => item.saleAttrValueName != inputValue)
      // console.log (result)
      if (!result) {
        this.$message ('属性值不能重复')
        row.inputVisible = false
        return
      }
      let newSaleAttrValue = {baseSaleAttrId, saleAttrValueName: inputValue}
      row.spuSaleAttrValueList.push (newSaleAttrValue)
      row.inputVisible = false
    },
    // 删除属性值
    handleClose(row, index) {
      row.spuSaleAttrValueList.splice (index, 1)
    },
    // 删除属性
    deleteAttr (index) {
      this.spu.spuSaleAttrList.splice (index, 1)
    },
    // 保存（要区分是保存还是修改，区别在于回去留在第一页还是当前页）
    async addOrUpdateSpu () {
      // 整理照片墙参数，需要携带imageName和imageUrl
      this.spu.spuImageList = this.spuImageList.map ((item) => {
        return {
          imgName: item.name,
          imgUrl: (item.response && item.response.data) || item.url
        }
      })
      let result = await this.$API.spu.reqAddOrUpdateSpu (this.spu)
      // console.log (result)
      if (result.code == 200) {
      this.$message ({type: 'success', message: '保存成功'})
      // （要区分是保存还是修改，区别在于回去留在第一页还是当前页）
      this.$emit ('changeScene', {scene: 0, flag: this.spu.id? '修改': '添加'})
      }
      // 清数据
      Object.assign (this._data, this.$options.data ())
    },
    // 点击添加spu按钮发2个请求 父组件通知到的
    async addSpuData (category3Id) {
      // 收集三级分类id
      this.spu.category3Id = category3Id
      // 获取品牌的请求
      let tradeMarkResult = await this.$API.spu.reqTradeMarkList ()
      if (tradeMarkResult.code == 200) {
        this.tradeMarkList = tradeMarkResult.data
      }
      // 获取销售属性
      let saleResult = await this.$API.spu.reqBaseSaleAttrList () 
      if (saleResult.code == 200) {
        this.saleAttrList = saleResult.data
      }
    },
    // 取消按钮
    cancel () {
      this.$emit ('changeScene', {scene: 0, flag: ''})
      // 清数据
      Object.assign (this._data, this.$options.data ())
    }
  },
  computed: {
    // 计算出未选择的销售属性 必须有返回值
    unSelectSaleAttr () {
      // saleAttrList数据-spu.spuSaleAttrList  数组的过滤 filter  every返回一个布尔值
      let result = this.saleAttrList.filter (item => {
        return this.spu.spuSaleAttrList.every (item1 => {
          return item.name != item1.saleAttrName
        })
      })
      return result
    }
  }
}
</script>

<style>
  .el-tag + .el-tag {
    margin-left: 10px;
  }
  .button-new-tag {
    margin-left: 10px;
    height: 32px;
    line-height: 30px;
    padding-top: 0;
    padding-bottom: 0;
  }
  .input-new-tag {
    width: 90px;
    margin-left: 10px;
    vertical-align: bottom;
  }
</style>
